#ifndef EMS_SERVICE_DATA_COLLECTOR_H
#define EMS_SERVICE_DATA_COLLECTOR_H

#include "device/DeviceBase.h"

#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

namespace ems {

namespace device {
    class DeviceManager;
}

namespace service {

class DataCollector {
public:
    using DataCollectionCallback = std::function<void(const std::string& deviceId, const std::vector<device::DataValue>& data)>;
    using DataErrorCallback = std::function<void(const std::string& deviceId, const std::string& error)>;

    DataCollector();
    ~DataCollector();

    bool initialize(device::DeviceManager* deviceManager);
    void start();
    void stop();

    bool isRunning() const { return running_; }

    void setCollectionInterval(int intervalSeconds) { collectionInterval_ = intervalSeconds; }
    int getCollectionInterval() const { return collectionInterval_; }

    void setDataCallback(DataCollectionCallback callback) { dataCallback_ = callback; }
    void setErrorCallback(DataErrorCallback callback) { errorCallback_ = callback; }

    uint64_t getTotalCollections() const { return totalCollections_; }
    uint64_t getSuccessfulCollections() const { return successfulCollections_; }
    uint64_t getFailedCollections() const { return failedCollections_; }
    uint64_t getLastSuccessfulCollectionTs() const { return lastSuccessfulCollectionTs_; }
    uint64_t getTotalPointsCollected() const { return totalPointsCollected_; }

private:
    std::atomic<bool> running_;
    std::thread collectorThread_;
    std::atomic<int> collectionInterval_;

    device::DeviceManager* deviceManager_;
    DataCollectionCallback dataCallback_;
    DataErrorCallback errorCallback_;

    std::condition_variable sleepCv_;
    std::mutex sleepMutex_;

    std::atomic<uint64_t> totalCollections_;
    std::atomic<uint64_t> successfulCollections_;
    std::atomic<uint64_t> failedCollections_;
    std::atomic<uint64_t> lastSuccessfulCollectionTs_;
    std::atomic<uint64_t> totalPointsCollected_;

    void collectionLoop();
    bool collectFromDevice(device::DeviceBase* device);
    uint64_t getCurrentTimestamp() const;
};

}  // namespace service
}  // namespace ems

#endif  // EMS_SERVICE_DATA_COLLECTOR_H
